package compiler;

import static d3d11.D3D11.*;
import static d3d11.D3D11.D3D_DRIVER_TYPE.*;
import static org.bridj.Pointer.*;
import static org.junit.Assert.assertEquals;

import org.bridj.Pointer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import d3d11.core.ID3D10Blob;
import d3d11.core.ID3D11Device;
import d3d11.core.ID3D11DeviceContext;
import d3d11.shader.ID3D11VertexShader;
import static d3dcompiler.D3DCompiler.*;

public class TestCompiler {

	ID3D11Device device;
	ID3D11DeviceContext immediateContext;
	
	@After
	public void destroy() {
		// Release objects
		immediateContext.Release();
		device.Release();
	}
	
	@Before
	public void init() {
		
		Pointer<Pointer<ID3D11Device>> pDevice = allocatePointer(ID3D11Device.class);
		Pointer<Pointer<ID3D11DeviceContext>> pDeviceContext = allocatePointer(ID3D11DeviceContext.class);
		
		// Create device
		int result = D3D11CreateDevice(null, 
						  D3D_DRIVER_TYPE_HARDWARE,
						  null, 
						  0, 
						  null, 
						  0, 
						  D3D11_SDK_VERSION, 
						  pDevice, 
						  null, 
						  pDeviceContext);
		
		assertEquals(0, result);
		
		device = new ID3D11Device(pDevice.get());
		immediateContext = new ID3D11DeviceContext(pDeviceContext.get());
	}
	
	@Test
	public void compileShaders() {
		
		String vertexShader = "float4 VS( float4 Pos : POSITION ) : SV_POSITION " +
							  "{ " +
							  "		return Pos;" +
							  "}";
		//String pixelShader = "float4 PS( float4 Pos : SV_POSITION ) : SV_Target { return float4( 1.0f, 1.0f, 0.0f, 1.0f );    // Yellow, with Alpha = 1}";	
		
		Pointer<Pointer<ID3D10Blob>> ppCode = allocatePointer(ID3D10Blob.class);
		Pointer<Pointer<ID3D10Blob>> ppErrorMsgs = allocatePointer(ID3D10Blob.class);
		int result = D3DCompile(pointerToCString(vertexShader), vertexShader.length(), null, null, null, pointerToCString("VS"), pointerToCString("vs_5_0"), 0, 0, ppCode, ppErrorMsgs);
		assertEquals(0, result);
		
		ID3D10Blob vsCode = ppCode.get().getNativeObject(ID3D10Blob.class);
		Pointer<Pointer<ID3D11VertexShader>> ppVS = allocatePointer(ID3D11VertexShader.class);
		result = device.CreateVertexShader(vsCode.GetBufferPointer(), (int)vsCode.GetBufferSize(), null, ppVS);
		assertEquals(0, result);
		
		ID3D11VertexShader vs = ppVS.get().getNativeObject(ID3D11VertexShader.class);
		result = vs.Release();
		assertEquals(0, result);
	}
}
